package com.notice.util;


import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.LogFactory;
import com.notice.config.LogNoticeException;
import com.notice.config.LogSpringContent;
import com.notice.entity.AsyncManager;
import com.notice.entity.LogDingInfo;
import com.notice.message.Text;
import com.notice.message.TextMessage;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;


/**
 * 钉钉机器人短信发送
 *
 * @Author dzl
 * @Date 2022/1/4 4:08 下午
 */
public class DingRobot {
    /**
     * 请求超时时间
     */
    private static final LogDingInfo LOG_DING_INFO = LogSpringContent.getLogDingInfo();


    private static final String TEXT = "text";

    private static final String CODE = "errcode";


    public static void sendTextMessage(String message) {
        AsyncManager.me().execute(() -> DingRobot.syncSendTextMessage(message));
    }


    /**
     * 同步发送信息
     *
     * @param url     地址
     * @param message 消息内容
     * @param at      @的对象
     */
    public static void syncSendTextMessage(String message) {
        LogSpringContent.getRateLimit().acquire();
        Long timestamp = System.currentTimeMillis();
        String sign = getSecret(timestamp, LOG_DING_INFO.getSecret());
        TextMessage textMessage = new TextMessage();
        textMessage.setAt(LOG_DING_INFO.getAt());
        textMessage.setMsgtype(TEXT);
        Text text = new Text();
        text.setContent(message);
        textMessage.setText(text);

        /*url添加加签信息*/
        String sb = LOG_DING_INFO.getWebHook() + "&timestamp=" +
                timestamp +
                "&sign=" +
                sign;
        /*发送请求*/
        try {
            String post = HttpUtil.post(sb, JSONUtil.toJsonStr(textMessage), LOG_DING_INFO.getTimeout());
            JSONObject jsonObject = JSONUtil.parseObj(post);
            if (0 != jsonObject.get(CODE, Integer.class)) {
                LogFactory.get().warn("日志发往钉钉失败：".concat(post));
            }
        } catch (Exception e) {
            throw new LogNoticeException("钉钉报警连接超时", e);
        }
    }

    /**
     * @param timestamp 时间戳
     * @param secret    key
     * @return /
     */
    private static String getSecret(final Long timestamp, final String secret) {
        try {
            String stringToSign = timestamp + "\n" + secret;
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
            byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
            return URLEncoder.encode(new String(Base64.getEncoder().encode(signData)), "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException("钉钉加签失败", e);
        }
    }
}
